package com.lhkk.inventoryvehicle.camera

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.graphics.ImageFormat
import android.graphics.SurfaceTexture
import android.hardware.camera2.CameraAccessException
import android.hardware.camera2.CameraCaptureSession
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraDevice
import android.hardware.camera2.CameraManager
import android.hardware.camera2.CaptureRequest
import android.hardware.camera2.TotalCaptureResult
import android.media.Image
import android.media.ImageReader
import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
import android.util.Log
import android.util.Size
import android.util.SparseIntArray
import android.view.Surface
import android.view.SurfaceHolder
import android.view.SurfaceView
import android.widget.FrameLayout
import androidx.annotation.NonNull
import java.util.*
import java.util.concurrent.Semaphore
import java.util.concurrent.TimeUnit

class Camera2Helper(private val mContext: Context, private val mSurfaceView: SurfaceView) {

    private val TAG = "Camera2Helper"
    // 使用主线程的 Handler，用于在主线程执行任务
    private val mainHandler = Handler(Looper.getMainLooper())

    // 相机设备对象
    private var mCameraDevice: CameraDevice? = null

    // 预览会话对象
    private var mCaptureSession: CameraCaptureSession? = null

    // 预览请求构建器
    private var mPreviewRequestBuilder: CaptureRequest.Builder? = null

    // 预览请求
    private var mPreviewRequest: CaptureRequest? = null

    // 用于接收静态图像的 ImageReader
    private var mImageReader: ImageReader? = null

    // 后台线程，用于处理相机相关的任务
    private var mBackgroundThread: HandlerThread? = null

    // 后台线程的 Handler
    private var mBackgroundHandler: Handler? = null

    // 用于确保在关闭相机之前不会退出应用程序
    private val mCameraOpenCloseLock = Semaphore(1)

    // 相机 ID，这里默认使用后置摄像头
    private var mCameraId: String? = null

    // 相机特性
    private var mCameraCharacteristics: CameraCharacteristics? = null

    // 预览尺寸
    private var mPreviewSize: Size? = null

    // 拍照尺寸
    private var mImageSize: Size? = null

    // 存储期望的预览旋转角度 (0, 90, 180, 270)
    private var mDesiredPreviewRotation = 0

    // 将屏幕旋转角度映射到 JPEG 方向
    private val ORIENTATIONS = SparseIntArray().apply {
        append(Surface.ROTATION_0, 90)
        append(Surface.ROTATION_90, 0)
        append(Surface.ROTATION_180, 270)
        append(Surface.ROTATION_270, 180)
    }

    // 相机设备状态回调
    private val mStateCallback = object : CameraDevice.StateCallback() {
        override fun onOpened(@NonNull cameraDevice: CameraDevice) { // 相机成功打开时调用
            mCameraOpenCloseLock.release()
            mCameraDevice = cameraDevice
            Log.d(TAG,
                "Camera opened successfully. Posting createCameraPreviewSession to main thread.") // 将创建预览会话的操作 POST 到主线程
            mainHandler.post { createCameraPreviewSession() }
        }

        override fun onDisconnected(@NonNull cameraDevice: CameraDevice) { // 相机断开连接时调用
            mCameraOpenCloseLock.release()
            cameraDevice.close()
            mCameraDevice = null
            Log.d(TAG, "Camera disconnected.")
        }

        override fun onError(@NonNull cameraDevice: CameraDevice, error: Int) { // 相机打开出错时调用
            mCameraOpenCloseLock.release()
            cameraDevice.close()
            mCameraDevice = null
            val errorMsg = when (error) {
                ERROR_CAMERA_IN_USE -> "Camera in use" //                ERROR_MAX_CAMERAS_ACCESSED -> "Max cameras accessed"
                ERROR_CAMERA_DISABLED -> "Camera disabled"
                ERROR_CAMERA_DEVICE -> "Fatal camera device error"
                ERROR_CAMERA_SERVICE -> "Fatal camera service error"
                else -> "Unknown camera error: $error"
            }
            Log.e(TAG, "CameraDevice.StateCallback onError: $errorMsg")
        }
    }

    // 捕获会话状态回调
    private val mSessionStateCallback = object : CameraCaptureSession.StateCallback() {
        override fun onConfigured(@NonNull cameraCaptureSession: CameraCaptureSession) { // 会话配置完成时调用
            mCaptureSession = cameraCaptureSession
            Log.d(TAG,
                "CameraCaptureSession configured. Posting configureSurfaceViewLayout to main thread.") // 将调整 SurfaceView 布局的操作 POST 到主线程 (因为布局操作需要访问 UI 元素)
            (mContext as Activity).runOnUiThread {
                configureSurfaceViewLayout(mSurfaceView.width, mSurfaceView.height)
            }

            try { // 设置自动对焦模式
                mPreviewRequestBuilder?.set(CaptureRequest.CONTROL_AF_MODE,
                    CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE) // 设置自动白平衡模式
                mPreviewRequestBuilder?.set(CaptureRequest.CONTROL_AWB_MODE,
                    CaptureRequest.CONTROL_AWB_MODE_AUTO) // 设置自动曝光模式
                mPreviewRequestBuilder?.set(CaptureRequest.CONTROL_AE_MODE,
                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH)

                // 设置 JPEG 方向，确保拍照结果方向正确
                val rotation = (mContext as Activity).windowManager.defaultDisplay.rotation
                mPreviewRequestBuilder?.set(CaptureRequest.JPEG_ORIENTATION,
                    getOrientation(rotation))


                // 构建预览请求
                mPreviewRequest = mPreviewRequestBuilder?.build() // 设置重复捕获请求，开始预览
                // 检查 mPreviewRequest 是否为 null
                mPreviewRequest?.let {
                    mCaptureSession?.setRepeatingRequest(it, mCaptureCallback, mBackgroundHandler)
                    Log.d(TAG, "Repeating preview request set.")
                } ?: run {
                    Log.e(TAG, "Preview request is null, cannot start repeating request.")
                }


            } catch (e: CameraAccessException) {
                Log.e(TAG, "Failed to set repeating request", e)
            }
        }

        override fun onConfigureFailed(@NonNull cameraCaptureSession: CameraCaptureSession) { // 会话配置失败时调用
            Log.e(TAG, "CameraCaptureSession onConfigureFailed")
        }
    }

    // 捕获回调，用于处理捕获结果
    private val mCaptureCallback =
        object : CameraCaptureSession.CaptureCallback() { // 可以根据需要在这里处理捕获结果，例如判断对焦状态等
        }

    // ImageReader 图像可用回调
    private val mOnImageAvailableListener =
        ImageReader.OnImageAvailableListener { reader -> // 当有新的图像可用时调用
            mBackgroundHandler?.post(ImageSaver(reader.acquireNextImage()))
        }

    // 用于保存图像的 Runnable
    private inner class ImageSaver(private val mImage: Image?) : Runnable {
        override fun run() {
            if (mImage == null) {
                Log.e(TAG, "ImageSaver received null image")
                return
            }
            val buffer = mImage.planes[0].buffer
            val bytes = ByteArray(buffer.remaining())
            buffer.get(bytes) // TODO: 在这里实现图像的保存逻辑，例如保存到文件
            Log.d(TAG, "Captured image data size: ${bytes.size}") // 例如：保存到文件
            // File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "pic_" + System.currentTimeMillis() + ".jpg");
            // try (FileOutputStream output = new FileOutputStream(file)) {
            //     output.write(bytes);
            //     Log.d(TAG, "Saved: " + file.getAbsolutePath());
            // } catch (IOException e) {
            //     Log.e(TAG, "Error saving image", e);
            // } finally {
            //     mImage.close(); // 确保图像被关闭
            // }
            mImage.close() // 确保图像被关闭
        }
    }

    init { // 确保 SurfaceView 已经创建并持有 Surface
        mSurfaceView.holder.addCallback(object : SurfaceHolder.Callback {
            override fun surfaceCreated(@NonNull holder: SurfaceHolder) { // Surface 创建时打开相机
                Log.d(TAG, "Surface created. Opening camera.") // 在 Surface 可用时打开相机，并传递 Surface 的尺寸
                openCamera(mSurfaceView.width, mSurfaceView.height)
            }

            override fun surfaceChanged(@NonNull holder: SurfaceHolder,
                format: Int,
                width: Int,
                height: Int) { // Surface 尺寸改变时重新配置预览会话和布局
                Log.d(TAG,
                    "Surface changed. Width: $width, Height: $height. Reconfiguring preview.") // 重新配置预览会话以使用新的 Surface 尺寸
                // 将创建预览会话的操作 POST 到主线程
                mainHandler.post {
                    createCameraPreviewSession()
                } // 根据新的 Surface 尺寸调整 SurfaceView 的布局
                // configureSurfaceViewLayout(width, height) // Moved to onConfigured
            }

            override fun surfaceDestroyed(@NonNull holder: SurfaceHolder) { // Surface 销毁时关闭相机
                Log.d(TAG, "Surface destroyed. Closing camera.")
                closeCamera()
            }
        })
    }

    /**
     * 设置期望的预览画面旋转角度。
     * 在下一次配置预览会话时生效。
     *
     * @param rotationDegrees 期望的旋转角度 (0, 90, 180, 270)
     */
    fun setPreviewRotation(rotationDegrees: Int) {
        mDesiredPreviewRotation = rotationDegrees % 360
        Log.d(TAG, "Desired preview rotation set to: $mDesiredPreviewRotation degrees")
        // 如果相机已打开且有预览会话，重新配置以应用新的旋转设置
        if (mCameraDevice != null && mCaptureSession != null) {
            Log.d(TAG, "Camera active, reconfiguring preview session for new rotation.")
            mainHandler.post { createCameraPreviewSession() }
        }
    }


    /**
     * 打开指定尺寸的相机。
     * 需要 CAMERA 权限。
     */
    @SuppressLint("MissingPermission")
    fun openCamera(width: Int, height: Int) {

        // 启动后台线程
        startBackgroundThread()

        val manager = mContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager
        try { // 尝试获取相机打开锁，超时 2500ms
            if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
                throw RuntimeException("Time out waiting to lock camera opening.")
            }

            // 遍历所有相机，找到后置摄像头并获取其特性
            for (cameraId in manager.cameraIdList) {
                val characteristics = manager.getCameraCharacteristics(cameraId)

                // 不使用前置摄像头
                val facing = characteristics.get(CameraCharacteristics.LENS_FACING)
                if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {
                    continue
                }

                // 获取 StreamConfigurationMap，其中包含相机支持的输出尺寸
                val map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
                    ?: continue

                // 选择最大的可用 JPEG 尺寸作为拍照尺寸
                mImageSize = Collections.max(Arrays.asList(*map.getOutputSizes(ImageFormat.JPEG)),
                    CompareSizesByArea())
                Log.d(TAG, "Selected image size: ${mImageSize?.width}x${mImageSize?.height}")

                // 创建 ImageReader 来处理拍照数据
                mImageSize?.let { size ->
                    mImageReader = ImageReader.newInstance(size.width,
                        size.height,
                        ImageFormat.JPEG, /*maxImages*/
                        2).apply {
                        setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler)
                    }
                } ?: run {
                    Log.e(TAG, "Image size not determined, cannot create ImageReader.")
                    mCameraOpenCloseLock.release()
                    return
                }


                // 选择适合预览的尺寸
                // 对于 SurfaceView，可以使用 map.getOutputSizes(SurfaceHolder.class) 或 map.getOutputSizes(SurfaceTexture.class)
                // 这里使用 SurfaceTexture.class，通常与 TextureView 兼容的尺寸也适用于 SurfaceView
                val outputSizes = map.getOutputSizes(SurfaceTexture::class.java)
                if (outputSizes == null) {
                    Log.e(TAG, "No output sizes available for preview.")
                    mCameraOpenCloseLock.release()
                    return
                }

                mImageSize?.let { size -> // 选择最佳预览尺寸，使用 SurfaceView 的宽高作为参考
                    mPreviewSize = chooseOptimalSize(outputSizes, width, height, size)
                    Log.d(TAG,
                        "Selected preview size: ${mPreviewSize?.width}x${mPreviewSize?.height}")
                } ?: run {
                    Log.e(TAG, "Image size not determined, cannot choose preview size.")
                    mCameraOpenCloseLock.release()
                    return
                }


                // 存储相机特性，用于后续获取传感器方向等信息
                mCameraCharacteristics = characteristics
                mCameraId = "1"
                Log.d(TAG, "Found back facing camera with ID: $mCameraId")
                break // 找到后置摄像头后退出循环
            }

            // 如果没有找到后置摄像头
            if (mCameraId == null) {
                Log.e(TAG, "Failed to find a back facing camera")
                mCameraOpenCloseLock.release() // 确保在出错时释放锁
                return
            }

        } catch (e: CameraAccessException) {
            Log.e(TAG, "CameraAccessException in openCamera", e)
            mCameraOpenCloseLock.release() // 确保在出错时释放锁
            return
        } catch (e: InterruptedException) {
            throw RuntimeException("Interrupted while trying to lock camera opening.", e)
        } catch (e: NullPointerException) { // 当设备支持 Camera2 API 但不支持特定硬件级别时可能发生
            Log.e(TAG, "Camera2 API not fully supported on this device.", e)
            mCameraOpenCloseLock.release() // 确保在出错时释放锁
            return
        }

        // 如果找到相机并获取了 ID，则打开相机设备
        try {
            mCameraId?.let {
                manager.openCamera(it, mStateCallback, mBackgroundHandler)
            } ?: run {
                Log.e(TAG, "Camera ID is null, cannot open camera.")
                mCameraOpenCloseLock.release() // 确保在出错时释放锁
            }

        } catch (e: CameraAccessException) {
            Log.e(TAG, "Failed to open camera", e)
            mCameraOpenCloseLock.release() // 确保在出错时释放锁
        }
    }

    /**
     * 关闭相机。
     */
    fun closeCamera() {
        try { // 尝试获取相机打开锁，超时 2500ms
            mCameraOpenCloseLock.acquire()
            mCaptureSession?.close()
            mCaptureSession = null
            mCameraDevice?.close()
            mCameraDevice = null
            mImageReader?.close()
            mImageReader = null
            Log.d(TAG, "Camera, session, and image reader closed.")
        } catch (e: InterruptedException) {
            throw RuntimeException("Interrupted while trying to lock camera closing.", e)
        } finally {
            mCameraOpenCloseLock.release()
        } // 停止后台线程
        stopBackgroundThread()
    }

    /**
     * 创建相机预览会话。
     */
    private fun createCameraPreviewSession() { // 在创建会话前检查必要的对象是否已初始化
        if (mCameraDevice == null || mPreviewSize == null) {
            Log.e(TAG, "Cannot create camera preview session. Dependencies are null.")
            return
        }

        // 获取 SurfaceView 的 Surface
        val previewSurface = mSurfaceView.holder.surface
        if (previewSurface == null || !previewSurface.isValid) {
            Log.e(TAG, "SurfaceView Surface is null or invalid, cannot create preview session.")
            return
        }
        Log.d(TAG, "SurfaceView Surface is valid. Created preview Surface from SurfaceView.")


        try { // 创建预览请求构建器
            mPreviewRequestBuilder =
                mCameraDevice?.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW) // 将 SurfaceView 的 Surface 添加到预览请求的输出
            mPreviewRequestBuilder?.addTarget(previewSurface)

            // 获取设备显示旋转角度
            val activity = mContext as Activity // Cast to Activity to access windowManager
            val displayRotation = activity.windowManager.defaultDisplay.rotation // 获取相机传感器方向
            val sensorOrientation =
                mCameraCharacteristics?.get(CameraCharacteristics.SENSOR_ORIENTATION) ?: 0

            // 计算预览所需的总旋转角度 (用于信息日志，不直接应用到 Surface)
            val totalRotation = (sensorOrientation - ORIENTATIONS.get(displayRotation) + 360) % 360
            Log.d(TAG,
                "Display rotation: $displayRotation, Sensor orientation: $sensorOrientation, Total preview rotation needed: $totalRotation")

            // 配置 SurfaceView 的布局以正确显示预览
            // configureSurfaceViewLayout(mSurfaceView.width, mSurfaceView.height) // Moved to onConfigured


            val surfaces = ArrayList<Surface>().apply {
                add(previewSurface)
                mImageReader?.surface?.let { add(it) } ?: Log.w(TAG,
                    "ImageReader surface is null, session will only have preview.")
            }


            // 创建相机捕获会话
            if (mCameraDevice != null && surfaces.isNotEmpty()) {
                mCameraDevice?.createCaptureSession(surfaces,
                    mSessionStateCallback,
                    mBackgroundHandler)
                Log.d(TAG, "Creating camera preview session.")
            } else {
                Log.e(TAG,
                    "Cannot create camera preview session. Camera device is null or surfaces list is empty.")
            }


        } catch (e: CameraAccessException) {
            Log.e(TAG, "Failed to create camera preview session", e)
        }
    }

    /**
     * 配置 SurfaceView 的布局参数以正确显示预览。
     * 这个方法通过调整 SurfaceView 的尺寸和位置来匹配预览画面的期望显示效果。
     *
     * @param viewWidth  SurfaceView 容器的当前宽度
     * @param viewHeight SurfaceView 容器的当前高度
     */
    private fun configureSurfaceViewLayout(viewWidth: Int, viewHeight: Int) {
        // 在应用变换前检查 mPreviewSize 是否已确定
        if (mPreviewSize == null) {
            Log.e(TAG, "Preview size is null, cannot configure SurfaceView layout.")
            return
        }

        // 获取相机预览尺寸
        val previewWidth = mPreviewSize!!.width
        val previewHeight = mPreviewSize!!.height

        // 获取 SurfaceView 容器尺寸
        val containerWidth = viewWidth
        val containerHeight = viewHeight

        Log.d(TAG,
            "configureSurfaceViewLayout: Container dimensions: ${containerWidth}x${containerHeight}, Preview size: ${previewWidth}x${previewHeight}, Desired rotation: $mDesiredPreviewRotation")

        // 根据期望的预览旋转角度，确定在布局计算中使用的预览尺寸
        val rotatedPreviewWidth: Int
        val rotatedPreviewHeight: Int

        when (mDesiredPreviewRotation) {
            0, 180 -> {
                // 期望预览方向与原始预览尺寸方向一致 (例如，原始是横向，期望也是横向)
                rotatedPreviewWidth = previewWidth
                rotatedPreviewHeight = previewHeight
            }
            90, 270 -> {
                // 期望预览方向与原始预览尺寸方向垂直 (例如，原始是横向，期望是竖向)
                rotatedPreviewWidth = previewHeight
                rotatedPreviewHeight = previewWidth
            }
            else -> {
                // 默认情况，使用原始预览尺寸
                rotatedPreviewWidth = previewWidth
                rotatedPreviewHeight = previewHeight
            }
        }

        // 计算调整后的预览尺寸与容器尺寸的宽高比
        val rotatedPreviewAspectRatio = rotatedPreviewWidth.toFloat() / rotatedPreviewHeight
        val containerAspectRatio = containerWidth.toFloat() / containerHeight


        val scaledWidth: Int
        val scaledHeight: Int
        val offsetX: Int
        val offsetY: Int

        // 根据调整后的预览尺寸和容器尺寸的宽高比，计算缩放和偏移量
        if (containerAspectRatio > rotatedPreviewAspectRatio) {
            // 容器比调整后的预览更宽 (或者调整后的预览比容器更高)
            // 将调整后的预览高度缩放到容器高度，并计算宽度
            scaledHeight = containerHeight
            scaledWidth = (containerHeight * rotatedPreviewAspectRatio).toInt()
            offsetX = (containerWidth - scaledWidth) / 2
            offsetY = 0
            Log.d(TAG, "configureSurfaceViewLayout: Container wider than rotated preview. Scaling to height.")
        } else {
            // 容器比调整后的预览更高 (或者调整后的预览比容器更宽)
            // 将调整后的预览宽度缩放到容器宽度，并计算高度
            scaledWidth = containerWidth
            scaledHeight = (containerWidth / rotatedPreviewAspectRatio).toInt()
            offsetX = 0
            offsetY = (containerHeight - scaledHeight) / 2
            Log.d(TAG, "configureSurfaceViewLayout: Container taller than rotated preview. Scaling to width.")
        }


        Log.d(TAG, "configureSurfaceViewLayout: Calculated scaled size: ${scaledWidth}x${scaledHeight}, Offset: ${offsetX}x${offsetY}")


        // 更新 SurfaceView 的布局参数
        val layoutParams = mSurfaceView.layoutParams
        layoutParams.width = scaledWidth
        layoutParams.height = scaledHeight

        // 如果使用 FrameLayout，可以通过设置边距来实现居中
        if (layoutParams is FrameLayout.LayoutParams) {
            layoutParams.leftMargin = offsetX
            layoutParams.topMargin = offsetY
            Log.d(TAG, "Applying FrameLayout margins: left=$offsetX, top=$offsetY")
        } else {
            Log.w(TAG,
                "SurfaceView is not in a FrameLayout, cannot apply margins for centering.") // 如果不是 FrameLayout，您可能需要使用其他布局属性或父布局的特性来实现居中
        }


        mSurfaceView.layoutParams = layoutParams

        Log.d(TAG,
            "Configured SurfaceView layout. Scaled size: ${scaledWidth}x${scaledHeight}, Offset: ${offsetX}x${offsetY}")

        // Add logs to verify the applied layout parameters
        mSurfaceView.post {
            Log.d(TAG, "SurfaceView actual layout after apply: width=${mSurfaceView.width}, height=${mSurfaceView.height}, x=${mSurfaceView.x}, y=${mSurfaceView.y}")
        }
    }


    /**
     * 拍照。
     */
    fun takePicture() {
        if (mCameraDevice == null || mCaptureSession == null) {
            Log.e(TAG, "Cannot take picture. Camera or session is null.")
            return
        }

        try { // 创建拍照请求构建器
            val captureBuilder =
                mCameraDevice?.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE) // 将 ImageReader 的 Surface 添加到拍照请求的输出
            mImageReader?.surface?.let {
                captureBuilder?.addTarget(it)
            } ?: run {
                Log.e(TAG, "ImageReader surface is null, cannot take picture.")
                return
            }


            // 设置拍照时的相机参数 (可以根据需要进行调整)
            // 例如，可以使用与预览相同的自动对焦、白平衡、曝光模式
            captureBuilder?.set(CaptureRequest.CONTROL_AF_MODE,
                CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE)
            captureBuilder?.set(CaptureRequest.CONTROL_AWB_MODE,
                CaptureRequest.CONTROL_AWB_MODE_AUTO)
            captureBuilder?.set(CaptureRequest.CONTROL_AE_MODE,
                CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH)

            // 设置 JPEG 方向，确保照片方向正确
            val rotation = (mContext as Activity).windowManager.defaultDisplay.rotation
            captureBuilder?.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation))

            // 停止重复的预览请求，准备拍照
            mCaptureSession?.stopRepeating() // 提交单次拍照请求
            val captureRequest = captureBuilder?.build()
            if (captureRequest != null) {
                mCaptureSession?.capture(captureRequest,
                    object : CameraCaptureSession.CaptureCallback() {
                        override fun onCaptureCompleted(@NonNull session: CameraCaptureSession,
                            @NonNull request: CaptureRequest,
                            @NonNull result: TotalCaptureResult) {
                            super.onCaptureCompleted(session, request, result)
                            Log.d(TAG, "Picture capture completed.") // 拍照完成后，可以恢复预览
                            // 将创建预览会话的操作 POST 到主线程
                            mainHandler.post { createCameraPreviewSession() }
                        }
                    },
                    mBackgroundHandler)
                Log.d(TAG, "Sent picture capture request.")
            } else {
                Log.e(TAG, "Capture request build failed.")
            }


        } catch (e: CameraAccessException) {
            Log.e(TAG, "Failed to take picture", e)
        }
    }

    /**
     * 启动后台线程。
     */
    private fun startBackgroundThread() {
        if (mBackgroundThread == null || mBackgroundThread?.isAlive == false) {
            Log.d(TAG, "Starting background thread.")
            mBackgroundThread = HandlerThread("CameraBackground").also { it.start() }
            mBackgroundHandler = Handler(mBackgroundThread?.looper!!)
        }
    }

    /**
     * 停止后台线程。
     */
    private fun stopBackgroundThread() {
        mBackgroundThread?.quitSafely()
        try {
            mBackgroundThread?.join()
            mBackgroundThread = null
            mBackgroundHandler = null
            Log.d(TAG, "Background thread stopped.")
        } catch (e: InterruptedException) {
            Log.e(TAG, "Interrupted while stopping background thread", e)
        }
    }

    /**
     * 选择最佳的预览尺寸。
     * 尝试找到一个与目标宽高比匹配且不大于容器尺寸的尺寸。
     *
     * @param choices 可用的输出尺寸列表
     * @param viewWidth SurfaceView 的宽度
     * @param viewHeight SurfaceView 的高度
     * @param aspectRatio 期望的宽高比 (通常使用拍照尺寸的宽高比)
     * @return 最佳的预览尺寸
     */
    private fun chooseOptimalSize(choices: Array<Size>,
        viewWidth: Int,
        viewHeight: Int,
        aspectRatio: Size): Size { // 收集支持的、至少与预览 SurfaceView 同样大的尺寸
        val bigEnough = ArrayList<Size>() // 收集支持的、比预览 SurfaceView 小的尺寸
        val notBigEnough = ArrayList<Size>()
        val w = aspectRatio.width
        val h = aspectRatio.height

        // 根据设备方向调整 SurfaceView 的参考宽高，使其与预览方向一致
        val activity = mContext as Activity
        val rotation = activity.windowManager.defaultDisplay.rotation
        val isPortrait = when (rotation) {
            Surface.ROTATION_0, Surface.ROTATION_180 -> true
            else -> false
        }
        val rotatedViewWidth = if (isPortrait) viewWidth else viewHeight
        val rotatedViewHeight = if (isPortrait) viewHeight else viewWidth


        for (option in choices) {
            // 检查尺寸是否与期望的宽高比匹配
            // 增加对预览尺寸不为零的检查
            if (option.width != 0 && option.height != 0 &&
                option.height == option.width * h / w) {
                // 检查尺寸是否足够大
                if (option.width >= rotatedViewWidth && option.height >= rotatedViewHeight) {
                    bigEnough.add(option)
                } else {
                    notBigEnough.add(option)
                }
            }
        }

        // 如果找到足够大的尺寸，选择其中最小的一个
        return when {
            bigEnough.size > 0 -> Collections.min(bigEnough, CompareSizesByArea())
            notBigEnough.size > 0 -> Collections.max(notBigEnough, CompareSizesByArea())
            else -> {
                Log.e(TAG,
                    "Couldn't find any suitable preview size for the given aspect ratio. Using largest available.") // 如果没有找到合适的尺寸，返回支持的尺寸中最大的一个，不考虑宽高比
                // 过滤掉尺寸为零的选项，然后选择最大的
                choices.filter { it.width != 0 && it.height != 0 }
                    .maxWithOrNull(CompareSizesByArea()) ?: Size(640, 480) // 提供一个默认尺寸以防万一
            }
        }
    }

    /**
     * 比较两个 Size 的面积。
     */
    internal class CompareSizesByArea : Comparator<Size> {
        override fun compare(lhs: Size, rhs: Size): Int { // 比较它们的面积
            return java.lang.Long.signum(lhs.width.toLong() * lhs.height - rhs.width.toLong() * rhs.getHeight())
        }
    }

    /**
     * 根据设备显示旋转角度计算 JPEG 方向。
     */
    private fun getOrientation(rotation: Int): Int { // SENSOR_ORIENTATION 是传感器输出图像相对于设备自然方向的旋转角度。
        // 例如，对于大多数后置摄像头，自然方向是竖屏，传感器方向通常是 90 度。
        // 显示旋转是设备当前方向相对于其自然方向的旋转。
        // JPEG 方向需要将传感器方向和显示旋转结合起来。
        val sensorOrientation =
            mCameraCharacteristics?.get(CameraCharacteristics.SENSOR_ORIENTATION) ?: 0

        // 计算 JPEG 方向
        return (ORIENTATIONS.get(rotation) + sensorOrientation + 270) % 360
    }
}